<template>
  <div
    ref="table"
    :id="id"
    class="advanced-table"
    :style="{ height: tableHeight }"
  >
    <!-- 数据表格 -->
    <s-table
      v-if="columnShow"
      ref="AdvanceTable"
      v-bind="{
        ...$options.propsData,
        columns: columnShow && columnData,
        title: undefined,
        loading: false,
      }"
      :data="loadData"
      :size="size"
      @expandedRowsChange="onExpandedRowsChange"
      @change="onChange"
      @expand="onExpand"
      :rowClassName="rowClassName"
      :rowSelection="showRowSelect ? rowSelection : null"
      :customRow="rowClick"
      :showTotal="showTotal"
      :customHeaderRow="customHeaderRow"
      :pageSize="pageSize"
      :scroll="scrollXY"
      :pagination="pagination"
      :showPagination="showPagination"
    >
      <span v-if="rownumbers" slot="serial" slot-scope="text, record, index">
        {{ index + 1 }}
      </span>
      <template
        slot-scope="text, record, index"
        :slot="slot"
        v-for="slot in scopedSlots"
      >
        <slot :name="slot" v-bind="{ text, record, index }"></slot>
      </template>
      <template :slot="slot" v-for="slot in slots">
        <slot :name="slot"></slot>
      </template>
      <template
        slot-scope="record, index, indent, expanded"
        :slot="$scopedSlots.expandedRowRender ? 'expandedRowRender' : ''"
      >
        <slot
          v-bind="{ record, index, indent, expanded }"
          :name="$scopedSlots.expandedRowRender ? 'expandedRowRender' : ''"
        ></slot>
      </template>
      <div
        v-for="(item, index) in columnData"
        :key="index"
        :slot="item.slotName"
      >
        <span>{{ $ct(item.slotName, item.defaultTitle) }}</span>
      </div>
      <!-- 自定义slot -->
      <div
        v-for="item in scopedSlotsKeys"
        :key="item"
        :slot="item + '_text'"
        slot-scope="text, record"
      >
        <div v-if="tableUuid == '6E0B29C222E740DC94C5354B2C538C83'">
          <div
            :class="getJDFXTdStyle(record, item)"
            v-if="item == 'staus_code'"
          ></div>
          <span
            v-else-if="item == 'deviation'"
            :class="getJDFXTdStyle(record, item)"
            >{{ getJDFXTdText(record, item) }}</span
          >
          <span v-else>{{ text }}</span>
        </div>
        <span v-else>{{ text }}</span>
        <!--  -->
      </div>
    </s-table>
    <!-- 右键菜单 start -->
    <!-- <div v-show="showRightMenu" :style="{ top: menuTop + 'px', left: menuLeft + 'px' }" class="right-menu"
			@mouseleave="mouseLeave">
			<action-columns :columns="columns" @reset="onColumnsReset" class="action">
				<template :slot="slot" v-for="slot in slots">
					<slot :name="slot"></slot>
				</template>
			</action-columns>
		</div> -->
  </div>
</template>

<script>
import { STable } from "@/components";
import ActionColumns from "@/components/table/advance/ActionColumns"; //右键显示表格列
import { debounce, deepClone } from "@/utils/index.js";
import { mapState } from "vuex";
export default {
  name: "AdvanceTable",
  components: {
    ActionColumns,
    STable,
  },
  props: {
    url: Object,
    tableLayout: String,
    bordered: Boolean,
    childrenColumnName: Array[String],
    columns: Array,
    components: Object,
    defaultExpandAllRows: Array[String],
    expandedRowKeys: Array[String],
    expandedRowRender: Function,
    expandIcon: Function,
    expandRowByClick: Boolean,
    expandIconColumnIndex: Number,
    footer: Function,
    indentSize: Number,
    loading: Boolean,
    locale: Object,
    pagination: Object,
    showPagination: {
      default: true,
      type: String | Boolean,
    },
    customRow: Function,
    rowKey: [String, Function],
    scroll: Object,
    showHeader: Boolean,
    size: {
      default: "small",
      type: String,
    },
    title: String,
    getPopupContainer: Function,
    transformCellText: Function,
    formatConditions: Boolean,
    queryParam: Object,
    customCell: Function,
    rownumbers: {
      default: true,
      type: Boolean,
    },
    type: String,
    showSearch: {
      type: Boolean,
      default: true,
    },
    pageSize: {
      type: Number,
    },
    rowSelectionType: {
      type: String,
      default: "checkbox",
    },
    showTotal: {
      type: Boolean,
      default: true,
    },
    showRowSelect: {
      type: Boolean,
      default: true,
    },
    initLoad: {
      type: Boolean,
      default: true,
    },
    translate: {
      type: Boolean,
      default: true,
    },
    scopedSlotsKeys: {
      type: Array,
      default: () => [],
    },
    tableUuid: {
      type: String,
      default: "",
    },
  },
  provide() {
    return {
      table: this,
    };
  },
  data() {
    return {
      id: `${new Date().getTime()}-${Math.floor(Math.random() * 10)}`,
      fullScreen: false,
      conditions: {},
      // 加载数据方法 必须为 Promise 对象
      loadData: (parameter) => {
        this.$pagerData = parameter;
        const url = this.type
          ? this.type === "master"
            ? this.url.masterList
            : this.url.subList
          : this.url.getPageSet;
        const requestParameters = Object.assign(
          {},
          parameter,
          this.queryParamObj
        );
        if (this.initLoad) {
          return this.$post(url, requestParameters).then((res) => {
            this.dataSource = res?.data?.rows || res.rows;
            return res?.data || res;
          });
        } else {
          return new Promise((resolve, reject) => {
            resolve({});
          });
        }
      },
      rowKeys: "", //表格行的唯一key值
      selectedRowKeys: [],
      selectedRows: [],
      rows: null,
      queryParamObj: {},
      showRightMenu: false,
      menuTop: "",
      menuLeft: "",
      dataSource: [],
      pageTableBoxHeight: 0, //单个表格高度
      pageTableBoxWidth: 0, //单个表格宽度
      toolbarTableHeight: 0,
      antbar: 0,
      antcontent: 0,
      pageClientHeight: 0, //使用固定的页面布局时的页面高度
      toolbarHeight: 0, //有表格操作按钮时的按钮高度
      paginationtHeight: 34, //分页组件的高度
      paginationtWidth: 0, // 分页组件的宽度
      columnData: [],
      columnShow: false,
      $pagerData: {},
    };
  },
  computed: {
    ...mapState("setting", ["rowSelectColor"]),
    // 插槽
    slots() {
      return Object.keys(this.$slots).filter((slot) => slot !== "title");
    },
    scopedSlots() {
      return Object.keys(this.$scopedSlots).filter(
        (slot) => slot !== "expandedRowRender" && slot !== "title"
      );
    },

    // 表格勾选的配置
    rowSelection() {
      return {
        columnWidth: 50,
        selectedRowKeys: this.selectedRowKeys,
        onChange: this.onSelectChange,
        onSelectAll: this.onSelectAll,
        onSelectInvert: this.onSelectInvert,
        type: this.rowSelectionType,
      };
    },
    // 表格竖向滚动条设置  这里是根据每页数据条数大于等于20的时候出现滚动条
    scrollXY() {
      let height = "";
      let paginationtHeight = this.paginationtHeight || 34;
      if (this.antcontent && this.antcontent > 0) {
        height =
          this.antcontent -
          this.toolbarHeight -
          this.antbar -
          60 -
          paginationtHeight;
      } else {
        // 57 -
        // 22 -
        height =
          this.pageClientHeight -
          this.toolbarHeight -
          this.antbar -
          60 -
          paginationtHeight;
      }
      const tdHeight = this.dataSource?.length * 47 ?? 0;
      let scroll = "";
      if (this.scroll)
        scroll = {
          x: this.scroll.x,
          y: this.scroll.y ? this.scroll.y : height,
        };
      let width = 0;
      this.columns.forEach((item) => {
        if (item.width) {
          width += item.width;
        }
      });
      return this.scroll
        ? scroll
        : this.dataSource?.length >= 20 || height < tdHeight
        ? {
            y: height,
            x: width,
          }
        : { x: width };
    },
    tableHeight() {
      let height = "";
      if (!this.toolbarHeight) {
        height = `calc(100% - 47px)`;
      } else {
        height = `calc(100% - ${this.toolbarHeight}px - 47px)`;
      }
      return height;
    },
  },
  created() {
    this.addListener();
    this.$bus.$on("updateTableColumns", (data) => {
      this.visibleColumns();
    });
  },
  // 组件销毁时移除监听事件
  beforeDestroy() {
    this.removeListener();
    this.destroyResizeEvent();
    // this.$bus.$off('updateTableColumns');
  },
  // 监听获取表格数据参数的变化
  watch: {
    queryParam: {
      handler(newVal, oldVal) {
        this.queryParamObj = newVal;
      },
      deep: true,
      immediate: true,
    },
    // 监听表头过滤
    columns: {
      deep: true,
      immediate: true,
      handler(newVal, oldVal) {
        this.columnData = newVal;
      },
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.resizeHandler();
    });

    this.initResizeEvent();
    this.visibleColumns();
  },
  methods: {
    getJDFXTdStyle(record = {}, key = "") {
      let { tableUuid } = this;
      //进度分析表单
      if (tableUuid == "6E0B29C222E740DC94C5354B2C538C83") {
        switch (key) {
          //项目状态
          case "staus_code":
            if (record[key] == "正常") {
              return "JDFX_STATUS_CODE_NORMAL";
            } else if (record[key] == "超期") {
              return "JDFX_STATUS_CODE_ERROR";
            } else {
              return "JDFX_STATUS_CODE_BEFORE";
            }
          //偏差
          case "deviation":
            let status = record["staus_code"];
            if (status == "正常") {
              return "JDFX_DEVIATION_NORMAL";
            } else if (status == "超期") {
              return "JDFX_DEVIATION_ERROR";
            } else {
              return "JDFX_DEVIATION_BEFORE";
            }

          default:
            break;
        }
      }
    },

    getJDFXTdText(record = {}, key = "") {
      let status = record["staus_code"];
      let days = record["duration"];
      if (status == "正常") {
        return "按时完成";
      } else if (status == "超期") {
        return `超期${days}天完成`;
      } else {
        return `提前${days}天完成`;
      }
    },
    // 显示隐藏表格列
    visibleColumns() {
      const list = localStorage.getItem("columns_" + this.$route.name);
      let columns;
      if (list) {
        columns = JSON.parse(list);
      } else {
        columns = deepClone(this.columns);
      }
      let serial = {
        title: "序号",
        width: 50,
        fixed: "left",
        align: "center",
        type: "serial",
        key: "serial",
        langCode: "serialNo",
        scopedSlots: {
          customRender: "serial",
        },
        visible: true,
      };
      if (
        this.rownumbers &&
        columns.filter((col) => col.type === "serial").length === 0
      ) {
        // this.columns.splice(0, 0, serial);
        columns.splice(0, 0, serial);
      }
      if (this.translate) {
        columns = this.$toI18nFormat(columns);
      }
      this.columnData = columns.filter(
        (col) => col.visible === true || !col.hasOwnProperty("visible")
      );
      this.columnShow = true;
    },
    // 重新调整表格高度
    resizeHandler() {
      let tableId = this.$refs.AdvanceTable?.$parent.$el.id; //当前数据表格的id
      // 获取菜单按钮的高度
      let toolbar = document.getElementById(tableId)?.previousElementSibling;
      // 判断表格工具栏是否存在
      if (toolbar && toolbar.className.indexOf("toolbar") >= 0) {
        this.toolbarHeight = document.getElementById(
          tableId
        )?.previousElementSibling?.clientHeight;
      }
      // 获取页面内容的高度
      this.pageClientHeight = document.getElementsByClassName(
        "page-common-layout"
      )[0]?.clientHeight;

      this.pageTableBoxWidth = document.getElementById(tableId)?.clientWidth;
      // 获取页面内容的高度
      const paginationt = this.$refs.AdvanceTable?.$children[0].$children[0]
        .$children[0].$children[1];
      if (paginationt) {
        this.paginationtHeight = document.getElementsByClassName(
          paginationt.$el.className
        )[0]?.clientHeight;

        if (
          document.getElementsByClassName(paginationt.$el.className)[0]
            ?.clientWidth
        ) {
          this.paginationtWidth = document.getElementsByClassName(
            paginationt.$el.className
          )[0]?.clientWidth;
        }
        // 分页器自适应
        if (this.paginationtWidth >= this.pageTableBoxWidth - 20) {
          this.$refs.AdvanceTable.localPagination.showQuickJumper = false;
          this.$refs.AdvanceTable.localPagination.showSizeChanger = false;
          this.$refs.AdvanceTable.localPagination.showTotal = () => "";
        }
        if (
          this.pageTableBoxWidth > 528 &&
          this.paginationtWidth < this.pageTableBoxWidth - 20
        ) {
          this.$refs.AdvanceTable.localPagination.showQuickJumper = true;
          this.$refs.AdvanceTable.localPagination.showSizeChanger = true;
          this.$refs.AdvanceTable.localPagination.showTotal = (total, range) =>
            this.showTotal
              ? this.$ct("tablePagingTotal", "共 " + total + " 条", {
                  total: total,
                })
              : "";
        }
      }

      this.pageTableBoxHeight = document.getElementById(tableId)?.clientHeight;
      // 获取tabs的高度

      let antIdBom = document.getElementById(tableId)?.parentNode.className; //当前数据表格的id
      this.antbar =
        antIdBom == "ant-card-body"
          ? document.getElementsByClassName("ant-tabs-bar")[0]?.clientHeight
          : 0;
      this.antcontent = document.getElementsByClassName(
        "page-common-box-content"
      )[0]?.clientHeight;
    },
    // 全部勾选
    onSelectAll(selected, selectedRows, changeRows) {
      this.$emit("onSelectAll", selected, selectedRows, changeRows);
    },
    onSelectInvert(selectedRows) {
      this.$emit("onSelectInvert", selectedRows);
    },
    // 勾选事件
    onSelectChange(selectedRowKeys, selectedRows) {
      this.selectedRowKeys = selectedRowKeys;
      this.selectedRows = selectedRows;
      this.$emit("onSelectChange", selectedRowKeys, selectedRows);
    },
    // 刷新
    refresh(parmar) {
      this.selectedRowKeys = [];
      this.selectedRows = [];
      this.rows = null;
      this.rowKeys = null;
      setTimeout(() => {
        if (this.$refs.AdvanceTable) this.$refs.AdvanceTable.refresh(parmar);
      }, 100);
    },
    // 全屏切换
    toggleScreen() {
      if (this.fullScreen) {
        this.outFullScreen();
      } else {
        this.inFullScreen();
      }
    },
    // 行点击事件
    rowClick(record, index) {
      const that = this;
      return {
        on: {
          click: () => {
            that.rowKeys = record[this.rowKey];
            that.rows = record;
            that.$emit("rowClick", record, index, that.rowKeys);
          },
        },
      };
    },
    // 格式化表头  主要用于右键显示操作列
    customHeaderRow() {
      return {
        on: {
          contextmenu: (e) => {
            e.preventDefault();
            // 显示
            this.showRightMenu = true;
            // 定位
            this.menuTop = e.clientY;
            this.menuLeft = e.clientX;
          },
        },
      };
    },
    mouseLeave(event) {
      this.showRightMenu = false;
      document.removeEventListener(
        "contextmenu",
        this.handleRemoveRightMenu,
        true
      );
    },
    // 选中行的样式
    rowClassName(row) {
      if (this.rowSelectColor) {
        return row[this.rowKey] === this.rowKeys ? "row-select-color" : ""; // 每条数据的唯一识别值
      } else {
        return row[this.rowKey] === this.rowKeys ? "bg-bray" : ""; // 每条数据的唯一识别值
      }
    },
    // 全屏
    inFullScreen() {
      const el = this.$refs.table;
      el.classList.add("beauty-scroll");
      if (el.requestFullscreen) {
        el.requestFullscreen();
        return true;
      } else if (el.webkitRequestFullScreen) {
        el.webkitRequestFullScreen();
        return true;
      } else if (el.mozRequestFullScreen) {
        el.mozRequestFullScreen();
        return true;
      } else if (el.msRequestFullscreen) {
        el.msRequestFullscreen();
        return true;
      }
      this.$message.warn("对不起，您的浏览器不支持全屏模式");
      el.classList.remove("beauty-scroll");
      return false;
    },
    outFullScreen() {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.webkitCancelFullScreen) {
        document.webkitCancelFullScreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
      }
      this.$refs.table.classList.remove("beauty-scroll");
    },
    onColumnsReset(conditions) {
      this.$emit("reset", conditions);
    },
    onExpandedRowsChange(expandedRows) {
      this.$emit("expandedRowsChange", expandedRows);
    },
    onChange(pagination, filters, sorter, options) {
      this.$emit("change", pagination, filters, sorter, options);
    },
    onExpand(expanded, record) {
      this.$emit("expand", expanded, record);
    },
    addListener() {
      document.addEventListener("fullscreenchange", this.fullScreenListener);
      document.addEventListener(
        "webkitfullscreenchange",
        this.fullScreenListener
      );
      document.addEventListener("mozfullscreenchange", this.fullScreenListener);
      document.addEventListener("msfullscreenchange", this.fullScreenListener);
      document.addEventListener(
        "contextmenu",
        this.handleRemoveRightMenu,
        true
      );
    },
    removeListener() {
      document.removeEventListener("fullscreenchange", this.fullScreenListener);
      document.removeEventListener(
        "webkitfullscreenchange",
        this.fullScreenListener
      );
      document.removeEventListener(
        "mozfullscreenchange",
        this.fullScreenListener
      );
      document.removeEventListener(
        "msfullscreenchange",
        this.fullScreenListener
      );
      document.removeEventListener(
        "contextmenu",
        this.handleRemoveRightMenu,
        true
      );
    },
    //监听resize
    initResizeEvent() {
      window.addEventListener("resize", this.resizeHandler, false);
    },
    //移除resize
    destroyResizeEvent() {
      window.removeEventListener("resize", this.resizeHandler);
    },
    fullScreenListener(e) {
      if (e.target.id === this.id) {
        this.fullScreen = !this.fullScreen;
      }
    },
    handleRemoveRightMenu() {
      this.showRightMenu = false;
    },
  },
};
</script>

<style lang="less" scoped="scoped">
/deep/.td-content {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.advanced-table {
  .JDFX_STATUS_CODE_NORMAL {
    background: url("~@/assets/img/icon_3.png");
    width: 24px;
    height: 24px;
    background-size: 100% 100%;
  }
  .JDFX_STATUS_CODE_ERROR {
    background: url("~@/assets/img/icon_2.png");
    width: 24px;
    height: 24px;
    background-size: 100% 100%;
  }
  .JDFX_STATUS_CODE_BEFORE {
    background: url("~@/assets/img/icon_1.png");
    width: 24px;
    height: 24px;
    background-size: 100% 100%;
  }
  .JDFX_DEVIATION_NORMAL {
    color: #1677ff;
  }
  .JDFX_DEVIATION_BEFORE {
    color: #239b53;
  }
  .JDFX_DEVIATION_ERROR {
    color: #ff2d2d;
  }
}

@import "./index.less";
</style>
